package com.wxproject.demo.Utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.serializer.SerializerFeature;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;

import org.springframework.util.ObjectUtils;

/*
 *项目名: WXTEST
 *文件名: EmailUtil
 *创建者: ZQF
 *创建时间:5/04/2021 17:41
 *描述: TODO
 */
public class JSONUtil {


    /**
     * 查询值
     *
     * @param obj
     * @param name
     * @param map
     */
    public static void getValForObj(Object obj, String name, Map<String, Object> map) {
        if (obj instanceof JSONObject) {
            getValForJObj((JSONObject) obj, name, map);
        }
        if (obj instanceof JSONArray) {
            getValForJArr((JSONArray) obj, name, map);
        }
    }

    /**
     * 查询所有值
     *
     * @param obj
     * @param map
     */
    public static void getForObj(Object obj, Map<String, Object> map) {
        if (obj instanceof JSONObject) {
            getForJObj((JSONObject) obj, map);
        }
        if (obj instanceof JSONArray) {
            getForJArr((JSONArray) obj, map);
        }
    }

    /**
     * 处理JsonAarray 对象查值
     *
     * @param arr
     * @param name
     * @param map
     */
    public static void getValForJArr(JSONArray arr, String name, Map<String, Object> map) {
        Iterator<Object> iner = arr.iterator();
        while (iner.hasNext()) {
            getValForObj(iner.next(), name, map);
        }
    }

    /**
     * 处理JsonAarray 对象查询所有值
     *
     * @param arr
     * @param map
     */
    public static void getForJArr(JSONArray arr, Map<String, Object> map) {
        Iterator<Object> iner = arr.iterator();
        while (iner.hasNext()) {
            getForObj(iner.next(), map);
        }
    }

    /**
     * 处理JsonObject 对象查值
     *
     * @param jobj
     * @param name
     * @param map
     */
    public static void getValForJObj(JSONObject jobj, String name, Map<String, Object> map) {
        for (Map.Entry<String, Object> entry : jobj.entrySet()) {
            if (StringUtils.equals(entry.getKey(), name)) {
                map.put(entry.getKey(), entry.getValue());
            }
            getForObj(entry.getValue(), map);
        }
    }

    /**
     * 处理JsonObject 对象查所有值
     *
     * @param jobj
     * @param map
     */
    public static void getForJObj(JSONObject jobj, Map<String, Object> map) {
        for (Map.Entry<String, Object> entry : jobj.entrySet()) {
            if (!map.containsKey(entry.getKey())) {
                map.put(entry.getKey(), entry.getValue());
            }
            getForObj(entry.getValue(), map);
        }
    }

    /**
     * 判断字符串是否可以转化为json对象
     *
     * @param content
     * @return
     */
    public static boolean isJsonObject(String content) {
        // 此处应该注意，不要使用StringUtils.isEmpty(),因为当content为"  "空格字符串时，JSONObject.parseObject可以解析成功，
        // 实际上，这是没有什么意义的。所以content应该是非空白字符串且不为空，判断是否是JSON数组也是相同的情况。
        if (StringUtils.isBlank(content)) {
            return false;
        }
        try {
            JSONObject jsonStr = JSONObject.parseObject(content);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 判断字符串是否可以转化为JSON数组
     *
     * @param content
     * @return
     */
    public static boolean isJsonArray(String content) {
        if (StringUtils.isBlank(content)) {
            return false;
        }
        StringUtils.isEmpty(content);
        try {
            JSONArray jsonStr = JSONArray.parseArray(content);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 判断是否可以按照map动态的key解析值
     *
     * @param content
     * @return
     */
    public static boolean isJsonMap(String content) {
        if (StringUtils.isBlank(content)) {
            return false;
        }
        StringUtils.isEmpty(content);
        try {
            LinkedHashMap<String, Object> jsonMap = JSON.parseObject(content, new TypeReference<LinkedHashMap<String, Object>>() {
            });
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 根据key获取value
     *
     * @param json 需要传入的JSON对象
     * @param keyName key的名称
     * @return
     */
    public static Object getJsonValueBykey(String json, String keyName) {
        if (StringUtils.isNotBlank(json) && StringUtils.isNotBlank(keyName)) {
            Map<String, Object> map = new HashMap<>();
            if (isJsonObject(json)) {
                JSONObject jsonObject = JSONObject.parseObject(json);
                getValForObj(jsonObject, keyName, map);
                return map.get(keyName);
            } else if (isJsonArray(json)) {
                JSONArray jsonArray = JSONArray.parseArray(json);
                getValForJArr(jsonArray, keyName, map);
            }
            return map.get(keyName);
        } else {
            return null;
        }
    }

    public Map<String, Object> getJsonKeyValueMap(String json) {
        if (StringUtils.isNotBlank(json)) {
            if (isJsonObject(json)) {
                JSONObject jsonObject = JSONObject.parseObject(json);
                Map<String, Object> map = new HashMap<>();
                getForObj(jsonObject, map);
                String labelJson = JSON.toJSONString(map, SerializerFeature.DisableCircularReferenceDetect);
                JSONObject labelJSONObject = JSONObject.parseObject(labelJson);
                Map<String, Object> newMap = labelJSONObject;
                return newMap;
            } else if (isJsonArray(json)) {
                JSONArray jsonArray = JSONArray.parseArray(json);
                Map<String, Object> newMap = new HashMap<>();
                for (int i = 0; i < jsonArray.size(); i++) {
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    Map<String, Object> map = new HashMap<>();
                    getForObj(jsonObject, map);
                    String labelJson = JSON.toJSONString(map, SerializerFeature.DisableCircularReferenceDetect);
                    JSONObject labelJSONObject = JSONObject.parseObject(labelJson);
                    newMap = (labelJSONObject);
                }
                return newMap;
            }
        } else {
            return null;
        }
        return null;
    }

    /**
     * 处理结果值
     *
     * @param obj 原值
     * @param object 新值
     * @return
     */
    @SuppressWarnings("unchecked")
    public Object handleObject(Object obj, Object object) {
        if (!ObjectUtils.isEmpty(object)) {//返回值不为空
            if (ObjectUtils.isEmpty(obj)) {//原值为空
                obj = object;//赋值
            } else {//原数据已有
                if (!(obj instanceof JSONArray)) {//原数据不是JSONArray
                    JSONArray jsonArray = new JSONArray();
                    jsonArray.add(obj);
                    obj = jsonArray;
                }
                if (object instanceof JSONArray) {//数据不是JSONArray
                    ((Collection<Object>) obj).addAll((JSONArray) object);
                } else {
                    ((Collection<Object>) obj).add(object);
                }
            }
        }
        return obj;
    }

    /**
     * 根据key从Json中取出值
     *
     * @param data 数据
     * @param key key
     * @return
     */
    public Object getObjectByJSONkey(Object data, String key) {
        if ((!ObjectUtils.isEmpty(data)) && StringUtils.isNotBlank(key)) {
            Object obj = null;
            if (data instanceof JSONObject) { //判断是否是对象
                JSONObject jsonObject = (JSONObject) data;
                Object keyobj = jsonObject.get(key);//取值
                jsonObject.remove(key);//删除已提取的值
                obj = handleObject(obj, keyobj);
                Set<String> keySet = jsonObject.keySet();//解析
                Iterator<String> iterator = keySet.iterator();
                while (iterator.hasNext()) {
                    String jsonKey = iterator.next();// 获得key
                    Object object = getObjectByJSONkey(jsonObject.get(jsonKey), key);
                    obj = handleObject(obj, object);
                }
            } else if (data instanceof JSONArray) { //是否是数组
                JSONArray jsonArray = (JSONArray) data;
                for (int i = 0; i < jsonArray.size(); i++) {
                    Object object = getObjectByJSONkey(jsonArray.get(i), key);
                    obj = handleObject(obj, object);
                }
            }
            return obj;
        }
        return null;
    }

    /**
     * 根据指定内容生成文件
     *
     * @param content 指定内容
     * @param file 生成的文件，如果已经存在，则覆盖
     */
    public static void createFile(String content, File file) {
        if ((!ObjectUtils.isEmpty(file)) && StringUtils.isNotBlank(content)) {
            String parentPath = file.getParent();
            if (StringUtils.isNotBlank(parentPath)) {
                File fileat = new File(parentPath);
                if (!fileat.exists()) {//目录不存在创建
                    fileat.mkdirs();
                }
                if (file.exists()) {//文件存在删除
                    fileat.delete();
                }
                OutputStreamWriter writer = null;
                FileOutputStream fileOut = null;
                //放入数据
                try {
                    fileOut = new FileOutputStream(file);
                    writer = new OutputStreamWriter(fileOut, "UTF-8");
                    writer.write(content);
                    writer.close();
                    fileOut.close();
                } catch (IOException e) {
                } finally {
                    if (writer != null) {
                        try {
                            writer.close();
                        } catch (IOException ex) {
                        }
                    }
                    if (fileOut != null) {
                        try {
                            fileOut.close();
                        } catch (IOException ex) {
                        }
                    }
                }
            } else {
            }
        } else {
        }
    }

    public static void main(String args[]) {
//
//      }
    }
}
